//
//  BudgetView.swift
//  Speek
//
//  Created by MikeHo on 2023/6/19.
//

import SwiftUI
import CoreData

struct BudgetView: View {
    
    @Binding var isEditBudget : Bool
    @Binding var isShowBudgetDateSelect : Bool
    @Binding var isEditBudgetSuccess : Bool
    @Binding var selectBudgetYear : String
    @Binding var selectBudgetMonth : String
    @State private var showingMonthlyBudget : monthlyBudget = monthlyBudget(budgetYear: "", budgetMonth: "", budgets: [])
    @State private var monthlyExpense : Double = 0.0
    @State private var isOutOfBudget = false
    @State private var monthlyBill : [BillDetail] = []
    @State private var budgetsArray : [BudgetDetail] = []
    
    
    //@Binding var editBudget : Bool
    
    let budgetType :[String] = ["学习","医疗","饮食","维修","旅行","运动","娱乐","购物","理财","其他"]
    
    @Environment(\.managedObjectContext) private var context
    
    var body: some View {
        VStack{
            
            //总预算视图
            TotalBudgetView
                .padding(.bottom)
            
            //分割线
            HStack{
                Text("各类别预算")
                    .bold()
                    .font(.headline)
                Circle()
                    .fill(.purple)
                    .overlay{
                        Circle()
                            .stroke(Color.white, lineWidth: 2)
                    }
                Rectangle()
                    .frame(height: 3)
                    .overlay{
                        Rectangle()
                            .fill(.purple)
                    }
            }
            .frame(height: 10)
            .padding(.bottom,5)
            
            //各类别预算视图
            ScrollView{
                LazyVStack{
                    ForEach($showingMonthlyBudget.budgets,id: \.id) { budget in
                        BudgetCardView(budget:budget,year: selectBudgetYear,month:selectBudgetMonth)
                    }
                }
            }
        }
        
        .preferredColorScheme(.dark)
        .onAppear {
            // 获取选定日期的预算和相关的账单数组
            updateMonthlyBudget()
        }
        .onChange(of: selectBudgetYear,perform:{ _ in
            updateMonthlyBudget()
        })
        .onChange(of: selectBudgetMonth,perform: { _ in
            updateMonthlyBudget()
        })
        .onChange(of: isEditBudgetSuccess,perform: { _ in
            updateMonthlyBudget()
        })
    }
    
    private func updateMonthlyBudget() {
            budgetsArray = getBudgets(forYear: selectBudgetYear, month: selectBudgetMonth, budgetTypes: budgetType)
            showingMonthlyBudget = monthlyBudget(budgetYear: selectBudgetYear, budgetMonth: selectBudgetMonth, budgets: budgetsArray)
            let monthlyBill = fetchBillDetails(year: selectBudgetYear, month: selectBudgetMonth, tag: false)
            monthlyExpense = calculateTotalAmount(bills: monthlyBill)
            isOutOfBudget = monthlyExpense > showingMonthlyBudget.totalBudget
        }
    
    func getBudgets(forYear year: String, month: String, budgetTypes: [String]) -> [BudgetDetail] {
        var budgets: [BudgetDetail] = []
        
        for type in budgetTypes {
            let fetchRequest: NSFetchRequest<BudgetDetail> = BudgetDetail.fetchRequest()
            fetchRequest.predicate = NSPredicate(format: "year == %@ AND month == %@ AND type == %@", year, month, type)
            
            do {
                let results = try context.fetch(fetchRequest)
                if let budget = results.first {
                    budgets.append(budget)
                } else {
                    let newBudget = BudgetDetail(context: context)
                    newBudget.year = year
                    newBudget.month = month
                    newBudget.type = type
                    newBudget.amount = 0.0
                                        
                    budgets.append(newBudget)
                }
            } catch {
                print("Error fetching budgets: \(error)")
            }
        }
        
        // 保存更改到数据库
        do {
            try context.save()
        } catch {
            print("Error saving context: \(error)")
        }
        
        return budgets
    }

    //计算账单花费总和
    private func calculateTotalAmount(bills: [BillDetail]) -> Double {
        let totalAmount = bills.reduce(0.0) { $0 + ($1.cost ) }
        return totalAmount
    }

}

//总预算卡片视图
extension BudgetView{
    private var TotalBudgetView : some View{
        VStack{
            //总预算图片、标题和日期
            HStack{
                //总预算图片
                Image("TotalBudget")
                    .frame(width: 60,height: 60)
                    .background(Color.white.cornerRadius(20))
                VStack(alignment:.leading){
                    Text("总预算")
                        .font(.title)
                    Text("\(selectBudgetYear)年\(selectBudgetMonth)月")
                        .font(.headline)
                }
                .bold()
                Spacer()
            }
            .padding(.vertical,20)
            .padding(.horizontal,20)
            //总预算使用情况
            if showingMonthlyBudget.totalBudget == 0 {
                HStack{
                    Text("预算未设置")
                }
                .padding(.horizontal,20)
                .bold()
                .font(.body)
           
            }else{
                if isOutOfBudget{
                    HStack{
                        Text("已超支（¥\(String(format: "%.2f", monthlyExpense))/\(String(format: "%.2f", showingMonthlyBudget.totalBudget))）")
                        Spacer()
                        Text("\(String(format:"%.2f",(monthlyExpense-showingMonthlyBudget.totalBudget)/showingMonthlyBudget.totalBudget*100))%")
                    }
                    .padding(.horizontal,20)
                    .bold()
                    .font(.body)
                    
                    ProgressView(value: getProgress(), total: 1)
                        .accentColor(Color.orange) // 设置进度条颜色
                        .frame(height: 10) // 设置进度条高度
                        .padding(.horizontal,20)
                }else{
                    HStack{
                        Text("已使用（¥\(String(format: "%.2f", monthlyExpense))/\(String(format: "%.2f", showingMonthlyBudget.totalBudget))）")
                        Spacer()
                        Text("\(String(format: "%.2f", monthlyExpense/showingMonthlyBudget.totalBudget*100))%")
                            .foregroundColor(Color(red: 0.596, green: 0.847, blue: 0.741))

                    }
                    .padding(.horizontal,20)
                    .bold()
                    .font(.body)
                    
                    ProgressView(value: monthlyExpense/showingMonthlyBudget.totalBudget , total: 1)
                        .accentColor(Color(red: 0.596, green: 0.847, blue: 0.741)) // 设置进度条颜色
                        .frame(height: 10) // 设置进度条高度
                        .padding(.horizontal,20)
                }
            }
            
            Spacer()
        }
        .preferredColorScheme(.dark)
        .background(LinearGradient(
            gradient: Gradient(colors: [Color(red:0.502,green: 0.4,blue: 0.678), Color(red:0.925,green: 0.435,blue: 0.658)]),
            startPoint: .topLeading,
            endPoint: .bottomTrailing
        ).cornerRadius(20))
        .frame(width: 390,height: 150)
        .padding(.top,10)
        .onAppear{
            if monthlyExpense > showingMonthlyBudget.totalBudget {
                isOutOfBudget = true
            }
        }
    }
    
    private func getProgress() -> Double{
        let progressPercentage = (monthlyExpense-showingMonthlyBudget.totalBudget)/showingMonthlyBudget.totalBudget
        if progressPercentage <= 1 {
            return progressPercentage
        }
        else{
            return 1.0
        }
    }
}

func fetchBillDetails(year: String, month: String, tag: Bool) -> [BillDetail] {
    let context = PersistenceController.shared.container.viewContext
    guard let yearInt = Int(year), let monthInt = Int(month) else {
        return []
    }
    
    let calendar = Calendar.current
    let dateComponents = DateComponents(year: yearInt, month: monthInt)
    let startDate = calendar.date(from: dateComponents)!
    let endDate = calendar.date(byAdding: .month, value: 1, to: startDate)!

    let predicates: [NSPredicate] = [
        NSPredicate(format: "date >= %@ AND date < %@", startDate as NSDate, endDate as NSDate),
        NSPredicate(format: "tag == %@", tag as NSNumber)
    ]
    
    let compoundPredicate = NSCompoundPredicate(andPredicateWithSubpredicates: predicates)
    
    let sortDescriptor = NSSortDescriptor(key: "date", ascending: false)
    
    let fetchRequest: NSFetchRequest<BillDetail> = BillDetail.fetchRequest()
    fetchRequest.predicate = compoundPredicate
    fetchRequest.sortDescriptors = [sortDescriptor]
    
    do {
        let results = try context.fetch(fetchRequest)
        return results
    } catch {
        print("Error fetching bills: \(error)")
        return []
    }
}
